package com.example.jetpack_viewmodel_livedata.sticky;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @introduce : 非粘性的LiveData
 * <p>
 * creattime : 2022/1/11
 * <p>
 * author : xiongyp
 **/
public class NonStickyMutableLiveData<T> extends MutableLiveData {
    private boolean stickFlag = false;//非粘性

    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
        super.observe(owner, observer);
        if (!stickFlag) {
            hook(observer);
        }
    }

    //在这里去改变onChange的流程
    private void hook(Observer<? super T> observer) {
        try {
            //得到mLastVersion
            //获取到LiveData类中的mObservers对象
            Class<LiveData> liveDataClass = LiveData.class;
            Field mObserversField = liveDataClass.getDeclaredField("mObservers");
            mObserversField.setAccessible(true);
            //获取到这个成员变量的对象
            Object mObserversObject = mObserversField.get(this);
            //得到Map对应的class对象
            Class<?> mObserversClass = mObserversObject.getClass();
            //获取到mObservers对象的get方法
            Method get = mObserversClass.getDeclaredMethod("get", Object.class);
            get.setAccessible(true);
            //执行get方法
            Object invokeEntry = get.invoke(mObserversObject, observer);
            //定义一个空的对象
            Object observerWraper = null;

            if (invokeEntry != null && invokeEntry instanceof Map.Entry) {
                observerWraper = ((Map.Entry) invokeEntry).getValue();
            }
            if (observerWraper == null) {
                throw new NullPointerException("observerWraper is null");
            }
            //得到observerWrapper的类对象， 编译擦除问题会引起多态冲突所以用getSuperclass
            Class<?> superclass = observerWraper.getClass().getSuperclass();
            Field mLastVersion = superclass.getDeclaredField("mLastVersion");
            mLastVersion.setAccessible(true);
            //2.得到mVersion
            Field mVersion = liveDataClass.getDeclaredField("mVersion");
            mVersion.setAccessible(true);
            //3.把mVersion的数据填入到mLastVersion中
            Object mVersionValue = mVersion.get(this);
            mLastVersion.set(observerWraper, mVersionValue);
//            stickFlag = true;//打开这一行，代表下次添加观察者的时候调用observe方法时保持粘性
        } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}
